// sales.js
import { CsDouble } from '../common/csDouble.js';
import { CsFundDouble } from '../common/csFundDouble.js';
import { DealFilter } from './dealFilter.js';
import { Definition } from '../common/definition.js';
import { Engine } from '../engine.js';
import { CommodityBatch } from '../inventory/inventory.js'
import { Util } from '../../utils/util.js';
import { MetalPurchaseTradeMode, MetalSalesTradeMode } from '../common/metalDefinition.js';
import { DocType } from '../common/docDefinition.js';

/**
 * 销售相关定义
 * 过滤条件
 */
export class SalesFilter extends DealFilter {
    constructor(storeId = null) {
        super(storeId);
    }

    /**
     * 克隆过滤器
     * @param {SalesFilter} filter 
     * @returns {SalesFilter}
     */
    static clone(filter) {
        let baseFilter = super.clone(filter);
        let instance = new SalesFilter();
        Object.assign(instance, baseFilter);
        return instance;
    }

    /**
     * 转换为JSON对象
     * @param {boolean} withState 
     * @returns {Object}
     */
    toJson(withState = false) {
        const ret = super.toJson(withState);
        return ret;
    }
}

/**
 * 销售货品（含税批次）
 */
export class CommodityBatchWithTax extends CommodityBatch {
    /** 无折扣 */
    static constNoDiscount = 100;

    /** @type {CsFundDouble} 折后单价 */
    _singlePriceWithDiscount;

    /** @type {CsFundDouble} 折后总价 */
    _batchPriceWithDiscount;

    /** @type {CsDouble} 税率 0.00-100.00 */
    _taxRate;

    /** @type {CsFundDouble} 税后折后单价 */
    _singlePriceAfterTax;

    /** @type {CsFundDouble} 税后总价 */
    _batchPriceWithTax;

    /** @type {boolean} 是否为赠品 */
    _isPromotional;


    /** @type {boolean} 
     * 贵金属期货模式，先结算后期再补货 
     * 只针对 SubCommodity 中 metalAccountTypeId 有关联到贵金属账户商品有效
     * */
    _metalSalesTradeMode = null;

    /** @type {boolean} 
     * 贵金属销售交易模式 
     * 只针对 SubCommodity 中 metalAccountTypeId 有关联到贵金属账户商品有效
     * */
    _metalPurchaseTradeMode = null;

    /**
   * 构造函数
   */
    constructor({
        commodity,  // SubCommodity
        count,  // CsDouble
        batchPrice,  // CsFundDouble
        singlePrice, // CsFundDouble
        discount = CommodityBatchWithTax.constNoDiscount,
        availableCount = 0,   // 可用库存
        inventoryCount = 0,   // 总库存数量
        taxRate,  // 为默从系统参数获取
        isPromotional = false,
        metalSalesTradeMode = null, //  MetalSalesTradeMode ,  
        metalPurchaseTradeMode = null, // MetalPurchaseTradeMode 
        referPrice,   // CsFundDouble  参考价

        isEmptyConstruction = false,  // 是否是空初始化，应对dart 多场景构建下，不初始化参数构造函数

    }) {
        super({
            commodity,
            count,
            inventoryCount,
            availableCount,
            batchPrice,
            singlePrice,
            discount,
            countAfterDiscount: count == null ? null : new CsDouble(count.value),
            referPrice,
        });

        if (isEmptyConstruction) {
            return;
        }



        const orgTaxRate = (taxRate != null && taxRate >= 0) ? taxRate : Engine.getOrgSettings().taxRate;


        this._taxRate = new CsDouble(orgTaxRate, Definition.gConstTaxRatePrecision);
        if (singlePrice != null && discount != null) {
            this._singlePriceWithDiscount = new CsFundDouble(
                singlePrice.value * discount / 100.0
            );

            this._singlePriceAfterTax = new CsFundDouble(
                singlePrice.value * discount / 100.0 * (1.0 + orgTaxRate / 100.0)
            );
        }

        if (batchPrice != null && discount != null) {
            this._batchPriceWithDiscount = new CsFundDouble(
                batchPrice.value * discount / 100.0
            );

            this._batchPriceWithTax = new CsFundDouble(
                batchPrice.value * discount / 100.0 * (1.0 + orgTaxRate / 100.0)
            );
        }

        this._isPromotional = isPromotional;

        this._metalSalesTradeMode = metalSalesTradeMode; // MetalTradeMode , 
        this._metalPurchaseTradeMode = metalPurchaseTradeMode; // MetalSalesTradeMode

        if (this._metalSalesTradeMode && this._metalPurchaseTradeMode) {
            // 两种模式只能存在一种，同时存在抛出异常
            throw new Error('贵金属销售交易模式和贵金属期货模式只能存在一种');
        }
    }

    // 参考价格目前只有贵金属使用，所有调用 _updateSalesPrices_ForMetalData
    set referPrice(referPrice) {
        //console.log('commodityBatchWithTax set referPrice', referPrice);
        super._referPrice = referPrice;
        super._singlePrice = new CsFundDouble(referPrice.value);

        if (this.isMetalTradeBatch) {
            this._updateSalesPrices_ForMetalData();
        } else {
            this._updateSalesPricesData();
        }

    }

    get referPrice() {
        return super.referPrice;
    }


    /** 折后单价 CsFundDouble*/
    get singlePriceWithDiscount() {
        return this._isPromotional ? CsFundDouble.zero() : this._singlePriceWithDiscount;
    }

    /** 折后总价不含税  CsFundDouble */
    get batchPriceWithDiscount() {
        return this._isPromotional ? CsFundDouble.zero() : this._batchPriceWithDiscount;
    }

    /** 税后单价 CsFundDouble*/
    get singlePriceAfterTax() {
        return this._isPromotional ? CsFundDouble.zero() : this._singlePriceAfterTax;
    }

    /**
     * 设定税后单价，会从税后单价反向触发折后价，原价以及总价计算
     * calcPriceBeforeDiscount 是否计算折前价格
     * @param {CsFundDouble} value 
     */
    setSinglePriceAfterTax(value) {
        if (this.discount.value === 0) return;
        this._singlePriceAfterTax = value;
        this._updateSalesPricesDataFromSinglePriceAfterTax();
    }

    /** 单价 CsFundDouble */
    get singlePrice() {
        return this._isPromotional ? CsFundDouble.zero() : super.singlePrice;
    }

    /** 折扣 CsDouble*/
    get discount() {
        return this._isPromotional ? new CsDouble(CommodityBatchWithTax.constNoDiscount) : this._discount;
    }

    // value CsDouble
    set discount(value) {
        super.discount = value;

        if (this.isMetalTradeBatch) {
            this._updateSalesPrices_ForMetalData();
        } else {
            this._updateSalesPricesData();
        }
    }

    /** 税率 CsDouble*/
    get taxRate() {
        return this._isPromotional ? CsDouble.zero() : this._taxRate;
    }

    // value CsDouble
    set taxRate(value) {
        if (value == null) {
            this._taxRate = CsDouble.zero();
        }
        else {
            this._taxRate = new CsDouble(
                value.value,
                Definition.gConstTaxRatePrecision
            );
        }
        this._updateSalesPricesData();
    }

    /** 总价  CsFundDouble*/
    get batchPrice() {
        return this._isPromotional ? CsFundDouble.zero() : super.batchPrice;
    }

    /** 税后总价  CsFundDouble*/
    get batchPriceWithTax() {
        return this._isPromotional ? CsFundDouble.zero() : this._batchPriceWithTax;
    }

    // 是否结算价格
    get isSettlePrice() {
        if (this._metalPurchaseTradeMode) {
            return this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettledPrice.code ||
                this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettleMetal_SettlePrice.code;
        }
        else if (this._metalSalesTradeMode) {
            return this._metalSalesTradeMode.code === MetalSalesTradeMode.SettledPrice.code ||
                this._metalSalesTradeMode.code === MetalSalesTradeMode.SettleMetal_SettlePrice.code;
        }

        return true;
    }

    // 是否来金
    get isSettleMetal() {
        if (this._metalPurchaseTradeMode) {
            return this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettleMetal_SettlePrice.code ||
                this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettleMetal.code;
        }
        if (this._metalSalesTradeMode) {
            return this._metalSalesTradeMode.code === MetalSalesTradeMode.SettleMetal_SettlePrice.code ||
                this._metalSalesTradeMode.code === MetalSalesTradeMode.SettleMetal.code;
        }

        return false;
    }

    // 应收，应付金额
    get expectMetalCount() {
        if (this._metalPurchaseTradeMode) {
            if (this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettleMetal_SettlePrice.code ||
                this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettledPrice.code) {
                return this.countAfterDiscount;
            }
        }
        else if (this._metalSalesTradeMode) {
            if (this._metalSalesTradeMode.code === MetalSalesTradeMode.SettleMetal_SettlePrice.code ||
                this._metalSalesTradeMode.code === MetalSalesTradeMode.SettledPrice.code) {
                return this.countAfterDiscount;
            }
        }

        return CsDouble.zero();
    }

    // 来金或付金
    get actualMetalCount() {
        if (this._metalPurchaseTradeMode) {
            if (this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettleMetal_SettlePrice.code ||
                this._metalPurchaseTradeMode.code === MetalPurchaseTradeMode.SettleMetal.code) {
                return this.countAfterDiscount;
            }
        }
        else if (this._metalSalesTradeMode) {
            if (this._metalSalesTradeMode.code === MetalSalesTradeMode.SettleMetal_SettlePrice.code ||
                this._metalSalesTradeMode.code === MetalSalesTradeMode.SettleMetal.code) {
                return this.countAfterDiscount;
            }
        }

        return CsDouble.zero();

    }

    get metalSalesTradeMode() {
        return this._metalSalesTradeMode;
    }
    set metalSalesTradeMode(value) {
        this._metalSalesTradeMode = value;
    }
    get metalPurchaseTradeMode() {
        return this._metalPurchaseTradeMode;
    }
    set metalPurchaseTradeMode(value) {
        //console.log("set metalPurchaseTradeMode", value);
        this._metalPurchaseTradeMode = value;
    }

    // 税后总价
    setBatchPriceWithTax(value, calcPriceBeforeDiscount = true) {

        if (this.discount?.value === 0) return;

        // 含税总价
        this._batchPriceWithTax = value;

        if(this._batchPriceWithTax == null){
            // 如果是清空，则不再进行下列结算
            return;
        }

        // 含税单价
        if (this.count != null && this.count.value != 0) {
            this._singlePriceAfterTax = new CsFundDouble(
                this._batchPriceWithTax.value / this.count.value
            );
        }

        // 折后不含税总价
        if (this.taxRate != null && this.taxRate.value != 0) {
            this._batchPriceWithDiscount = new CsFundDouble(
                this._batchPriceWithTax.value / (this.taxRate.value / 100.0 + 1)
            );
        } else {
            // 未设置税率或是税率为0，税前价格=税后价格
            this._batchPriceWithDiscount = new CsFundDouble(this._batchPriceWithTax.value);
        }

        // 折后不含税单价
        if (this.taxRate != null && this.taxRate.value != 0 && this.count != null && this.count.value != 0) {
            this._singlePriceWithDiscount = new CsFundDouble(
                this._batchPriceWithTax.value / (this.taxRate.value / 100.0 + 1) / this.count.value
            );
        }
        else if (this.taxRate == null && this.count != null && this.count.value != 0) {
            this._singlePriceWithDiscount = new CsFundDouble(
                this._batchPriceWithTax.value / this.count.value
            );
        }

        if (calcPriceBeforeDiscount) {

            if (this.taxRate != null && this.taxRate.value != 0 && this.discount != null && this.discount.value != 0) {
                // 折前总价
                this._batchPrice = new CsFundDouble(
                    (this._batchPriceWithTax.value / (this.taxRate.value / 100.0 + 1)) * 100 / this.discount.value
                );

                // 折前单价
                if (this.count != null) {
                    this._singlePrice = new CsFundDouble(
                        (this._batchPriceWithTax.value / (this.taxRate.value / 100 + 1)) * 100 / this.discount.value / this.count.value
                    );
                }
            }
            else if (this.taxRate == null && this.discount != null && this.discount.value != 0) {
                // 折前总价
                this._batchPrice = new CsFundDouble(
                    this._batchPriceWithTax.value / this.discount.value
                );

                // 折前单价
                if (this.count != null) {
                    this._singlePrice = new CsFundDouble(
                        this._batchPriceWithTax.value / this.discount.value / this.count.value
                    );
                }
            }



        }

        //console.log("setBatchPriceWithTax",this)
    }

    /** 税额  CsFundDouble*/
    get tax() {
        return this._isPromotional
            ? CsFundDouble.zero()
            : (this._batchPriceWithTax == null || this._batchPriceWithDiscount == null ? null :
                this._batchPriceWithTax.sub(this._batchPriceWithDiscount));
    }

    /** 是否为赠品 */
    get isPromotional() {
        return this._isPromotional;
    }

    // value bool
    set isPromotional(value) {
        this._isPromotional = value;
        this._updateSalesPricesData();
    }

    /**
     * @override
     * 减少数量 CsDouble
     */
    subtractCount(subCount) {
        const ret = super.subtractCount(subCount);
        this._updateSalesPricesData();
        return ret;
    }

    /**
     * @override
     * 增加数量 CsDouble
     */
    addCount(subCount) {
        const ret = super.addCount(subCount);
        this._updateSalesPricesData();
        return ret;
    }

    /**
     * @override
     * 设置数量 CsDouble
     */
    setCount(count) {
        const ret = super.setCount(count);

        if(count == null){
            this._batchPriceWithTax = null;
            this._batchPriceWithDiscount = null;
        }

        if (this.isMetalTradeBatch) {
            this._updateSalesPrices_ForMetalData();
        } else {
            this._updateSalesPricesData();
        }

        return ret;
    }

    /**
     * @override
     * 设置单价 CsFundDouble
     */
    setSinglePrice(price) {
        const ret = super.setSinglePrice(price);
        this._updateSalesPricesData();
        return ret;
    }

    /**
     * 设置折后单价
     * 以折后价计算所有关联价格
     * CsFundDouble
     */
    setSinglePriceWithDiscount(price) {
        this._singlePriceWithDiscount = price;
        if (this.singlePrice != null && this.singlePrice.value != 0) {
            this.discount = new CsDouble((price.value * 100.0 / this.singlePrice.value));
        }

        if (this.count != null || this.count.value != 0) {
            this._batchPriceWithDiscount = new CsFundDouble(
                this._singlePriceWithDiscount.value * this.count.value
            );
        }

        if (this.taxRate != null && this.taxRate.value != 0) {
            this._singlePriceAfterTax = new CsFundDouble(
                this._singlePriceWithDiscount.value * (1.0 + this.taxRate.value / 100.0)
            );
        }
        else {
            this._singlePriceAfterTax = new CsFundDouble(this._singlePriceWithDiscount.value);
        }

        return this._singlePriceAfterTax;
    }

    /**
     * 设置折后总价
     * 以折后总价计算所有关联价格
     * CsFundDouble
     */
    setBatchPriceWithDiscount(price) {
        this._batchPriceWithDiscount = price;

        // 折后单价
        if (this.count != null && this.count.value != 0) {
            this._singlePriceWithDiscount = new CsFundDouble(
                this._batchPriceWithDiscount.value / this.count.value
            );
        }

        // 按当前折扣率，计算折前单价
        if (this.discount != null && this.discount.value != 0 && this.count != null && this.count.value != 0) {
            const updateSinglePrice = new CsFundDouble(
                this._batchPriceWithDiscount.value * 100 / this._discount.value / this.count.value
            );
            this.setSinglePrice(updateSinglePrice);
        }

        // 再设置一次 _batchPriceWithDiscount，因为 setSinglePrice 会按折扣率重新计算一次 _batchPriceWithDiscount
        // 可能会因为精度问题，导致有1分钱的差异
        // 本处是设置折后总价，所以不需要再计算一次
        this._batchPriceWithDiscount = price;
        if (this.count != null && this.count.value != 0) {
            this._singlePriceWithDiscount = new CsFundDouble(
                this._batchPriceWithDiscount.value / this.count.value
            );
        }

        // 含税单价 使用 _batchPriceWithDiscount 计算避免精度缺失
        if (this.count != null && this.count.value != 0 && this.taxRate != null) {
            this._singlePriceAfterTax = new CsFundDouble(
                this._batchPriceWithDiscount.value / this.count.value * (1.0 + this.taxRate.value / 100.0)
            );
        }
        else if (this.count != null && this.count.value != 0 && this.taxRate == null) {
            this._singlePriceAfterTax = new CsFundDouble(
                this._batchPriceWithDiscount.value / this.count.value
            );
        }

        if (this.taxRate != null) {
            this._batchPriceWithTax = new CsFundDouble(
                this._batchPriceWithDiscount.value * (1.0 + this.taxRate.value / 100.0)
            );
        }
        else {
            this._batchPriceWithTax = new CsFundDouble(this._batchPriceWithDiscount.value);
        }

        return this._batchPriceWithDiscount;
    }

    /**
     * @override
     * 设置总价
     * CsFundDouble
     */
    setBatchPrice(price) {
        const ret = super.setBatchPrice(price);
        this._updateSalesPricesData();
        return ret;
    }

    /**
     * 更新售卖价格数据
     * batchPriceWithTaxCalcFromBatchPrice 最后含税价格是否采用不含税总价计算
     * 看使用场景，如果要从singlePrice 开始按折扣，税率计算，则 batchPriceWithTaxCalcFromBatchPrice = true
     * 是 _batchPriceWithTax 保留的精度更好
     * 如果是从_singlePriceAfterTax 计算 _batchPriceWithTax  则与税后价保持一致
     */
    _updateSalesPrices_ForMetalData() {

        // 900 -2,  700-900 -3, 750 -2, 700 -5

        console.log('_updateSalesPrices_ForMetalData');

        if (this.count != null & this.discount != null && this.singlePrice != null) {
            // 如果discount = 100.0 则无折扣
            if (this.discount.value === 100) {
                this._singlePriceWithDiscount = new CsFundDouble(
                    this.singlePrice.value,
                    2, true, true
                );
            }
            // 如果discount ≥ 90.0, 折后重量 = 原重量 * (discount - 2) / 1000
            else if (this._discount.value >= 90.0) {
                this._singlePriceWithDiscount = new CsFundDouble(
                    this.singlePrice.value * (this.discount.value - 0.2) / 100.0,
                    2, true, true
                );
            }
            // 如果discount = 750.0, 折后重量 = （discount - 2）/ 1000
            else if (this._discount.value == 75.0) {
                this._singlePriceWithDiscount = new CsFundDouble(
                    this.singlePrice.value * (this.discount.value - 0.2) / 100.0,
                    2, true, true
                );
            }
            // 如果discount在101-899之间, 折后重量 = 原重量 * (discount - 3) / 1000
            else if (this._discount.value >= 70 && this._discount.value < 90) {
                this._singlePriceWithDiscount = new CsFundDouble(
                    this.singlePrice.value * (this.discount.value - 0.3) / 100.0,
                    2, true, true
                );
            }
            // 如果discount在100-700之间, 折后重量 = 原重量 * (discount - 4) / 1000
            else if (this._discount.value >= 10 && this._discount.value < 70) {
                this._singlePriceWithDiscount = new CsFundDouble(
                    this.singlePrice.value * (this.discount.value - 0.5) / 100.0,
                    2, true, true
                );
            }
            // 其他情况按原逻辑处理 (discount为0-100之间的值)
            else {
                this._singlePriceWithDiscount = CsFundDouble.zero();
            }
        }



        if (this._singlePriceWithDiscount != null && this.count != null) {
            this._batchPriceWithDiscount = new CsFundDouble(
                this._singlePriceWithDiscount.value * this.count.value, 2, true, true
            );
        }

        if (this._singlePriceWithDiscount != null && this.taxRate != null) {
            this._singlePriceAfterTax = new CsFundDouble(
                this._singlePriceWithDiscount.value * (1.0 + this.taxRate.value / 100.0), 2, true, true
            );
        }
        else if (this._singlePriceWithDiscount != null && this.taxRate == null) {
            this._singlePriceAfterTax = new CsFundDouble(
                this._singlePriceWithDiscount.value, 2, true, true
            );
        }

        if (this._singlePriceAfterTax != null && this.count != null) {
            this._batchPriceWithTax = new CsFundDouble(this._singlePriceAfterTax.value * this.count.value, 2, true, true);
        }

    }

    /**
     * 更新售卖价格数据
     * batchPriceWithTaxCalcFromBatchPrice 最后含税价格是否采用不含税总价计算
     * 看使用场景，如果要从singlePrice 开始按折扣，税率计算，则 batchPriceWithTaxCalcFromBatchPrice = true
     * 是 _batchPriceWithTax 保留的精度更好
     * 如果是从_singlePriceAfterTax 计算 _batchPriceWithTax  则与税后价保持一致
     */
    _updateSalesPricesData(batchPriceWithTaxCalcFromBatchPrice = false) {
        let taxRatio = this.taxRate != null ? (1.0 + this.taxRate.value / 100.0) : 1.0;
        if (this.singlePrice != null && this.discount != null) {
            this._singlePriceWithDiscount = new CsFundDouble(
                this.singlePrice.value * this.discount.value / 100.0
            );
        }
        if (this.batchPrice != null && this.discount != null) {
            this._batchPriceWithDiscount = new CsFundDouble(
                this.batchPrice.value * this.discount.value / 100.0
            );
        }
        if (this.singlePrice != null && this.discount != null) {

            this._singlePriceAfterTax = new CsFundDouble(
                this.singlePrice.value * this.discount.value / 100.0 *
                taxRatio
            );
        }
        if (batchPriceWithTaxCalcFromBatchPrice) {
            if (this.batchPrice != null && this.discount != null) {
                this._batchPriceWithTax = new CsFundDouble(
                    this.batchPrice.value * this.discount.value / 100.0 *
                    taxRatio
                );
            }
        } else if (this._singlePriceAfterTax != null && this.count != null) {
            this._batchPriceWithTax = new CsFundDouble(this._singlePriceAfterTax.value * this.count.value);
        }
    }

    /**
     * 由税后单价更新价格
     */
    _updateSalesPricesDataFromSinglePriceAfterTax() {
        if (this.discount.value === 0) return;

        // 如果税后价是null, 清空折前价
        if (this.singlePriceAfterTax == null) {
            this._singlePriceWithDiscount = null;
            this._singlePrice = null;
            this._batchPriceWithTax = null;   // 暂时不清空总价, 根据情况调整  dml
            this._batchPriceWithDiscount = null;
            return;
        }

        let taxRatio = this.taxRate != null ? (1.0 + this.taxRate.value / 100.0) : 1.0;

        // step 1 计算折后单价
        if (this._singlePriceAfterTax != null) {
            const tmpPriceWithDiscount =
                this._singlePriceAfterTax.value / taxRatio;
            this._singlePriceWithDiscount = new CsFundDouble(tmpPriceWithDiscount);
        }



        // step 2 折后总价
        if (this._singlePriceAfterTax != null && this.count != null) {
            this._batchPriceWithDiscount = new CsFundDouble(
                this._singlePriceAfterTax.value * this.count.value / taxRatio
            );
        }

        // step 3 折后税后总价
        // 设定的是税后价，所以按税后单价计算税后总金额
        if (this._singlePriceAfterTax != null && this.count != null) {
            this._batchPriceWithTax = new CsFundDouble(
                this.count.value * this._singlePriceAfterTax.value
            );
        }


        // step 4 折前总价
        if (this._singlePriceAfterTax != null && this.count != null && this.discount != null) {
            this._batchPrice = new CsFundDouble(
                (this._singlePriceAfterTax.value * this.count.value / taxRatio) * 100 / this.discount.value
            );
        }


        // step 5 原价
        if (this._singlePriceAfterTax != null && this.discount != null) {
            this._singlePrice = new CsFundDouble(
                (this._singlePriceAfterTax.value / taxRatio) * 100 / this.discount.value
            );
        }

    }

    // 空对象，用于列表先创建空记录，后再选择商品场景
    static empty({ taxRate = null } = {}) {
        return new CommodityBatchWithTax({
            commodity: null,
            count: CsDouble.zero(),
            batchPrice: CsFundDouble.zero(),
            singlePrice: CsFundDouble.zero(),
            referPrice: CsFundDouble.zero(),
            taxRate: taxRate, // -1 为默认值，从系统参数获取
        });
    }

        // 空对象，用于列表先创建空记录，后再选择商品场景
    static emptyWithNull({ taxRate = null } = {}) {
        return new CommodityBatchWithTax({
            commodity: null,
            count: null,
            batchPrice: null,
            singlePrice: null,
            referPrice: null,
            taxRate: taxRate, // -1 为默认值，从系统参数获取
        });
    }

    /**
     * 从普通批次创建
     * @param {CommodityBatch} batch 
     */
    static fromCommodityBatch(batch) {
        let baseBatch = CommodityBatch.clone(batch);
        const instance = new CommodityBatchWithTax({ isEmptyConstruction: true });
        Object.assign(instance, baseBatch);

        //instance._discount = new CsDouble(CommodityBatchWithTax.constNoDiscount);
        instance._taxRate = CsDouble.zero();
        instance._singlePriceWithDiscount = batch.singlePrice;
        instance._batchPriceWithDiscount = batch.batchPrice;
        instance._singlePriceAfterTax = batch.singlePrice;
        instance._batchPriceWithTax = batch.batchPrice;
        instance._isPromotional = false;
        return instance;
    }

    /**
     * 简单模式创建
     * @param {CommodityBatchWithTax} batch 
     */
    static fromCommodityBatchWithTaxSimpleMode(batch) {
        let baseBatch = CommodityBatch.clone(batch);

        const instance = new CommodityBatchWithTax({ isEmptyConstruction: true });
        Object.assign(instance, baseBatch);

        // instance._discount = batch.discount;
        instance._taxRate = CsDouble.zero();
        instance._singlePriceWithDiscount = batch.singlePrice;
        instance._batchPriceWithDiscount = batch.batchPrice;
        instance._singlePriceAfterTax = batch.singlePrice;
        instance._batchPriceWithTax = batch.batchPrice;
        instance._isPromotional = batch._isPromotional;
        instance._metalPurchaseTradeMode = batch._metalPurchaseTradeMode;
        instance._metalSalesTradeMode = batch._metalSalesTradeMode;
        return instance;
    }

    /**
     * 不含税模式创建（优惠折扣保留）
     * @param {CommodityBatchWithTax} batch 
     */
    static fromCommodityBatchWithTaxZeroTaxMode(batch) {

        let baseBatch = CommodityBatch.clone(batch);

        const instance = new CommodityBatchWithTax({ isEmptyConstruction: true });
        Object.assign(instance, baseBatch);

        // instance._discount = batch.discount;
        instance._taxRate = CsDouble.zero();
        instance._singlePriceWithDiscount = batch._singlePriceWithDiscount;
        instance._batchPriceWithDiscount = batch.batchPriceWithDiscount;
        instance._singlePriceAfterTax = batch._singlePriceWithDiscount;
        instance._batchPriceWithTax = batch.batchPriceWithDiscount;
        instance._isPromotional = batch._isPromotional;
        return instance;
    }



    /**
     * 克隆
     * @param {CommodityBatchWithTax} data 
     */
    static clone(data) {
        let baseBatch = CommodityBatch.clone(data);
        const instance = new CommodityBatchWithTax({ isEmptyConstruction: true });
        Object.assign(instance, baseBatch);

        //  instance._discount = data._discount;
        instance._singlePriceWithDiscount = data._singlePriceWithDiscount;
        instance._batchPriceWithDiscount = data._batchPriceWithDiscount;
        instance._taxRate = data._taxRate;
        instance._singlePriceAfterTax = data._singlePriceAfterTax;
        instance._batchPriceWithTax = data._batchPriceWithTax;
        instance._isPromotional = data._isPromotional;
        return instance;
    }

    /**
     * @override
     * 拷贝数据
     */
    copy(batchData) {
        super.copy(batchData);
        const data = batchData;
        this._singlePriceWithDiscount = data._singlePriceWithDiscount;
        this._batchPriceWithDiscount = data._batchPriceWithDiscount;
        this._taxRate = data._taxRate;
        this._singlePriceAfterTax = data._singlePriceAfterTax;
        this._batchPriceWithTax = data._batchPriceWithTax;
        this._isPromotional = data._isPromotional;
    }

    /**
     * 从JSON创建
     * orderType  DocType
     */
    static fromJson(json, orderType) {
        let baseBatch = CommodityBatch.fromPurchaseSalesJson(json);

        const instance = new CommodityBatchWithTax({ isEmptyConstruction: true });

        Object.assign(instance, baseBatch);
        instance._singlePriceWithDiscount = Util.jsonToCsFundDouble(json.singlePriceAfterDiscount, 0);
        instance._batchPriceWithDiscount = Util.jsonToCsFundDouble(json.amountAfterDiscount, 0);
        instance._taxRate = Util.jsonToCsDouble(json.taxRate, 0, Definition.gConstTaxRatePrecision);
        instance._singlePriceAfterTax = Util.jsonToCsFundDouble(json.singlePriceWithTax, 0);
        instance._batchPriceWithTax = Util.jsonToCsFundDouble(json.amountWithTax, 0);
        instance._isPromotional = json.giveaway === undefined ? false : json.giveaway === 0;

        if (orderType && orderType.code == DocType.CGD.code && instance.isMetalTradeBatch && json.metalTradeMode != null) {
            instance.metalPurchaseTradeMode = MetalPurchaseTradeMode.fromCode(Util.jsonToInt(json.metalTradeMode));
        }
        else if (orderType && orderType.code == DocType.XSD.code && instance.isMetalTradeBatch && json.metalTradeMode != null) {
            instance.metalSalesTradeMode = MetalSalesTradeMode.fromCode(Util.jsonToInt(json.metalTradeMode));
        }

        return instance;
    }

    static fromJson_metalPurchaseTradeMode(json) {
        return CommodityBatchWithTax.fromJson(json, DocType.CGD)
    }

    static fromJson_metalSalesTradeMode(json) {
        return CommodityBatchWithTax.fromJson(json, DocType.XSD)
    }


    /**
     * 转换为JSON
     */
    toJson() {
        let ret = {
            commondityId: this.commodity.commodityId,
            commondityUnitId: this.commodity.unit.id,
            discount: this.discount.value,
            giveaway: this.isPromotional ? 0 : 1,
            id: this.id,
            singlePrice: this.singlePrice.value,
            referPrice: this.referPrice?.value,

            inoutStore: this.count.value,
            inoutStoreAfterDiscount: this.countAfterDiscount.value, // 折后数量
            specId: this.commodity.id,
            taxAmount: this.tax.value,
            taxRate: this.taxRate.value,
            amountAfterDiscount: this._batchPriceWithDiscount.value,
            singlePriceAfterDiscount: this._singlePriceWithDiscount.value,
            amountWithTax: this._batchPriceWithTax.value,
            singlePriceWithTax: this._singlePriceAfterTax.value,
            amountWithoutDiscountAndTax: this.batchPrice.value
        };

        if (this.metalPurchaseTradeMode) {
            ret.metalTradeMode = this.metalPurchaseTradeMode.code;
        }
        else if (this.metalSalesTradeMode) {
            ret.metalTradeMode = this.metalSalesTradeMode.code;
        }

        return ret;
    }

    /**
     * 转换为打印信息JSON（调试用）
     */
    toPrintInfoJson() {
        return {
            ...this.toJson(),
            commodityName: this.commodity.name
        };
    }
}